// call.js
function fn1 () {
    console.log(this)
    // console.log(this, arguments)
}
function fn2() {
    console.log(this)
}
// call 的特点
// 1. 可以改变我们当前函数的 this 指向
// 2. 还会让当前函数执行

// fn1.call('hello', '1', '2')

// Function.prototype.call = function (ctx) {
//     this()
// }

// fn1 的this 指向 fn2
// fn1.call(fn2)
// fn1.call.call.call(fn2)
// 等效于 call.call(fn2)

Function.prototype.call = function (context, args) {
    context = context ? Object(context) : window
    context.fn = this
    //存放参数
    let args = []
    for (let i = 0; i < arguments.length; i++) {
        args.push('arguments['+ i +']')        
    }
    let r = eval('context.fn('+ args +')')
    delete context.fn
    return r
}


Function.prototype.apply = function (context, args) {
    context = context ? Object(context) : window
    // js 不能直接修改 this 的指向 this = 'hello'
    context.fn = this
    if(!args) {
        return context.fn()
    }
    //存放参数
    let args = []
    for (let i = 0; i < arguments.length; i++) {
        args.push('arguments['+ i +']')        
    }
    let r = eval('context.fn('+ args +')')
    delete context.fn
    return r
}

fn1.call.call(fn2)
// this = 'hello' XXX.fn1()
// {}.fn = fn1
// 如果多个 call 会让 call 方法执行 并且把 call 方法中的 this 改变为 fn2
fn1.apply('hello', [111, 222])